//#include "stdafx.h"

#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <memory.h>

//#include "utility_new.h"

using namespace std;

#define IBUFSIZE 16

namespace KCore
{

int hexint(char c)
{
	int t = c;
	if (t < 0) {
		t += 0x100;
	}
	return t;
}

void hexdump_file(istream& ifile)
{
	char ibuff [IBUFSIZE];
	char obuff [(IBUFSIZE*2)+1];
	int i;

	while(!ifile.eof()) {
		memset(obuff, 0, (IBUFSIZE*2)+1);
		memset(ibuff, 0, IBUFSIZE);
		ifile.read(ibuff, IBUFSIZE);

		// corner case where file is exactly a multiple of
		// 16 bytes in length
		if(ibuff[0] == 0 && ifile.eof())
			break;

		for(i = 0; i < IBUFSIZE; i++) {
			if(ibuff[i] >= ' ')
				obuff[i] = ibuff[i];
			else
				obuff[i] = '.';

			cout << setfill('0') << setw(2) << hex
				<< hexint(ibuff[i]) << ' ';
		}
		cout << "  " << obuff << endl;
	}
	cout << dec ;
}

void hexdump_file(const char* filename)
{
	ifstream ifile(filename,ios_base::in | ios_base::binary);
	if(!ifile.is_open()) {
		cout << "Cannot Open " << filename << " for reading" << endl;
		return;
	}
	hexdump_file(ifile);
}

void hexdump(std::ostream& os, const char* buffer, size_t size)
{
	os << "size: " << size << endl;
	char ibuff[IBUFSIZE];
	char obuff[(IBUFSIZE*2)+1];
	const char* p = buffer;
	const char* end = buffer + size;

	while(p < end) {
		memset(obuff, 0, (IBUFSIZE*2)+1);
		memset(ibuff, 0, IBUFSIZE);
		int buf_size = min(IBUFSIZE, end-p);
		memcpy(ibuff, p, buf_size);
		p+=IBUFSIZE;
		for(int i = 0; i < buf_size; i++) {
			if(ibuff[i] >= ' ')
				obuff[i] = ibuff[i];
			else
				obuff[i] = '.';

			os << setfill('0') << setw(2) << hex
				<< hexint(ibuff[i]) << ' ';
		}
		os << "  " << obuff << endl;
	}
	os << dec ;
}


void hexdump(const char* buffer, size_t size)
{
	hexdump(cout, buffer, size);
}

void hexdump(std::string& str)
{
	hexdump(str.data(), str.size());
}

};
